home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / pctchnqs / 1990 / number6 / screen.cpp < prev    next >
Text File  |  1990-12-11  |  6KB  |  151 lines

  1. // Listing 5. SCREEN.CPP
  2. // C++ screen driver program that uses inline assembly
  3.  
  4. #pragma inline    // Inform compiler that we're doing inline assembly
  5. #include <bios.h>
  6.  
  7. class screen {        // Define a screen object with assembly methods
  8. public:
  9.   int wd, ht;         // Screen width and height
  10.   void far *vram;     // Pointer to video ram
  11.   screen(void);
  12.   void print(int x, int y, char far *charstr, char attr);
  13.   void hzfill(int x, int y, char fill, char attr, unsigned cnt);
  14.   void vtfill(int x, int y, char fill, char attr, unsigned cnt);
  15. };
  16.  
  17. screen::screen(void)
  18. // This constructor calls BIOS to get the current video mode,
  19. // ram pointer, display page, and screen width and height.
  20. {
  21.  asm {
  22.      mov   ah, 0x0f            // Fctn code to get video state
  23.      int   0x10                // Get video state into al, bh
  24.      mov   si, word ptr this   // Point to screen object data
  25.      push  ax                  // Save video mode
  26.      mov   ax, 0x1000          // Compute offset using page number
  27.      mov   bl, bh              // Set BX = page number
  28.      mov   bh, 0
  29.      mul   bx                  // Multiply by page no. to get offset
  30.      mov   [si].vram, ax       // Store offset in low word of vram
  31.      pop   ax                  // Restore video mode
  32.      cmp   al, 7               // Monochrome?
  33.      jnz   color
  34.      mov   [si].vram+2, 0xb000 // Use monochrome segment
  35.      jmp   short more
  36.  }
  37. color:
  38.  asm mov   [si].vram+2, 0xb800 // Use color segment
  39. more:
  40.  asm {
  41.      mov   ax, 0x0040          // Load ES:DI with 0x0040:0x004A
  42.      mov   es, ax              // which has current screen width
  43.      mov   ax, 0x004a
  44.      mov   di, ax
  45.      mov   ax, es:[di]         // Load AX with current screen width
  46.      mov   [si].wd, al         // Store width in screen object
  47.      mov   ax, 0x0084          // Load ES:DI with 0x0040:0x0084
  48.      mov   di, ax              // which has current screen height-1
  49.      mov   al, es:[di]         // AL = current screen height-1
  50.      inc   al
  51.      mov   ah, 0               // AX = screen height
  52.      mov   [si].ht, ax         // Store height in screen object
  53.  }
  54. }
  55.  
  56. void screen::print(int x, int y, char far *s, char attr)
  57. // Writes character string s with attribute attr at location (x,y)
  58. {
  59.  asm {
  60.      push  ds                      // Save DS register!
  61.      mov   si, word ptr this       // Point to screen object's data
  62.      mov   ax, [si].wd             // Load AX with screen width
  63.      mul   word ptr y              // Multiply by y
  64.      add   ax, word ptr x          // Add x
  65.      shl   ax, 1                   // Multiply by 2 to get offset
  66.      les   di, dword ptr [si].vram // Store video ram pointer in ES:DI
  67.      add   di, ax                  // Add in offset
  68.      lds   si, dword ptr s         // String pointer to DS:SI
  69.      mov   ah, byte ptr  attr      // Load ah with attribute
  70.  }
  71. cycle:
  72.      asm   lodsb            // Load next char into al (ah has attr)
  73.      asm   cmp al, 0        // Terminate when null char reached
  74.      asm   jz quit
  75.      asm   stosw            // Store char & attr, increment to next
  76.      asm   jmp short cycle  // Around the loop
  77. quit:
  78.      asm pop ds
  79. }
  80.  
  81. void screen::hzfill(int x, int y, char fill, char attr, unsigned cnt)
  82. // Fills a row of width cnt with the character fill, and attribute
  83. // attr at the relative screen location (x,y)
  84. {
  85.  asm {
  86.      mov   cx, word ptr cnt        // Load CX with fill count
  87.      jcxz  quit                    // Quit if CX = 0
  88.      mov   si, word ptr this       // Point to screen object's data
  89.      mov   ax, [si].wd             // Load AX with screen width
  90.      mul   word ptr y              // Multiply by y
  91.      add   ax, word ptr x          // Add x
  92.      shl   ax, 1                   // Multiply by two to get offset
  93.      les   di, dword ptr [si].vram // Store video ram pointer in ES:DI
  94.      add   di, ax                  // Add in offset
  95.      mov   al, byte ptr fill       // Load AX with char & attr
  96.      mov   ah, byte ptr attr
  97.      cld                           // Be sure to clear direction bit
  98.      rep   stosw                   // Store char & attr cnt times
  99.  }
  100. quit: return;
  101. }
  102.  
  103. void screen::vtfill(int x, int y, char fill, char attr, unsigned cnt)
  104. // Fills a column at location (x,y), using the fill character fill,
  105. // color attr, and making the fill cnt rows high
  106. {
  107.  asm {
  108.      mov   cx, word ptr cnt         // Load CX with fill count
  109.      jcxz  quit                     // Quit if cnt = 0
  110.      mov   si, word ptr this        // Point to screen object's data
  111.      mov   ax, [si].wd              // Load AX with screen width
  112.      mul   word ptr y               // Multiply by y
  113.      add   ax, word ptr x           // Add x
  114.      shl   ax, 1                    // Multiply by 2 to get offset
  115.      les   di, dword ptr [si].vram  // Store video pointer in ES:DI
  116.      add   di, ax                   // Add in offset
  117.      mov   al, byte ptr fill        // Load AX with char/attribute
  118.      mov   ah, byte ptr attr
  119.      mov   bx, [si].wd              // BX = (screen width-1) * 2
  120.      dec   bx                       // Which is offset to next row,
  121.      shl   bx, 1                    // same column
  122.      cld                            // Make sure direction bit cleared
  123.  }
  124. cycle:
  125.  asm {
  126.      stosw                          // Store char & attr in video ram
  127.      add   di, bx                   // Skip down to next row
  128.      loop  cycle                    // Loop until CX = 0
  129.  }
  130. quit: return;
  131. }
  132.  
  133. main()
  134. {
  135.     screen sc;  // Declare and initialize screen object
  136.  // Draw a black-on-cyan box around screen border
  137.     sc.hzfill(1, 0, 196, 0x30, sc.wd-2);
  138.     sc.hzfill(1, sc.ht-1, 196, 0x30, sc.wd-2);
  139.     sc.vtfill(0, 1, 179, 0x30, sc.ht-1);
  140.     sc.vtfill(sc.wd-1, 1, 179, 0x30, sc.ht-1);
  141.     sc.hzfill(0, 0, 218, 0x30, 1);
  142.     sc.hzfill(sc.wd-1, 0, 191, 0x30, 1);
  143.     sc.hzfill(0, sc.ht-1, 192, 0x30, 1);
  144.     sc.hzfill(sc.wd-1, sc.ht-1, 217, 0x30, 1);
  145.  // Fill in interior
  146.     for (int i=1; i<sc.ht-1; i++) sc.hzfill(1, i, ' ', 0x30, sc.wd-2);
  147.  // Write a message in the middle of the screen, wait for key press
  148.     sc.print(sc.wd/2-6, sc.ht/2, "PC Techniques", 0x30);
  149.     bioskey(0);
  150. }
  151.